package com.rtsapp.server.domain;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * 实体接口
 * 1. 使用JPA标注实体属性和实体之间的关系( 框架自行解析jpa注解 )
 * 2. 包含脏状态, 提供setDirty, isDirty, clearDirty三个方法, 用于数据同步的是否为脏的检测
 *     1. 如何置脏,  使用字节码生成的方式生成子类，进行自动的置脏处理
 *     2. dao如何使用脏状态进行操作
 *            if( isDirty() &&  clearDirty() ){
 *                  dao.update();
 *           }
 *     此处并未加锁, 同步数据时有可能是状态不一致的数据(因为业务线程和存储线程是不同线程，但是概率很小, 为了保证性能暂不加锁), 依赖不丢失dirty来保证数据会最终同步到数据库
 * 3. 子类应该是abstract, 使用统一的EntityBuilder来构造
 */
public abstract class IEntity implements java.io.Serializable {


    private final AtomicInteger dirtyTimes = new AtomicInteger();


    /**
     * 设置为dirty, dirty计数加一, 线程安全, 不会丢失计数
     */
    public final void setDirty() {
        //增加dirty次数
        dirtyTimes.incrementAndGet();
    }

    /**
     * 是否是脏的
     * @return
     */
    public final boolean isDirty(){
        return dirtyTimes.get() > 0;
    }

    /**
     * 此方法会清空dirty, 请清空后同步数据库
     * @return true 表示成功从脏状态恢复到非脏状态, false表示之前就是非脏状态, 提高该方法确保线程安全的清除
     */
    public final boolean clearDirty(){
        return dirtyTimes.getAndSet( 0 ) > 0 ;
    }



}
